/**
 * chinagoods.com
 * Copyright (c) 2020-2023 All Rights Reserved.
 */
package com.ruoyi.system.biz;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.core.page.PageDomain;
import com.ruoyi.common.enums.OrderStatusEnum;
import com.ruoyi.common.enums.OrderTypeEnum;
import com.ruoyi.common.exception.BusiException;
import com.ruoyi.common.utils.RequestUtil;
import com.ruoyi.common.utils.sign.SignMD5Util;
import com.ruoyi.system.domain.CashHistory;
import com.ruoyi.system.domain.Goods;
import com.ruoyi.system.domain.Order;
import com.ruoyi.system.dto.ApiNotifyDto;
import com.ruoyi.system.service.*;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @author yangpeng
 * Created by on 2023-12-08 10:11
 * @
 */
@Slf4j
@Component
public class BizOrderServiceImpl implements BizOrderService {


    @Resource
    private CashBizService cashService;

    @Resource
    private CashHistoryService cashHistoryService;
    @Resource
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;
    @Resource
    private ISysUserService userService;
    @Resource
    private ISysConfigService configService;
    @Resource
    private UserChannelService userChannelService;
    @Resource
    private ZfbConfigService zfbConfigService;
    @Resource
    private OrderService orderService;
    @Resource
    GoodsService goodsService;

    @Override
    public boolean finish(Long userId, Long id) {
        return false;
    }

    //超时补单 订单号
    @Override
    public boolean reduce(Long userId, Long id) {
        Order order = orderService.check(id);
        if (!StrUtil.equals(order.getStatus(), OrderStatusEnum.timeOut.getValue())) {
            throw new BusiException("该订单已处理完成");
        }
        order.setStatus("finish");
        order.setOrderStatus(OrderStatusEnum.success.getValue());
        String type = "";
        if (StrUtil.equals("支付宝", order.getBankName())) {
            type = "zfb";
        } else {
            type = "bank";
        }
        //扣除收款用户的金额
        CashHistory userCashHis = new CashHistory(userId, order.getAmount(), "reduce", "超时补单", "timeout");
        userCashHis.setOrderNo(order.getOrderNo());
        cashService.updateCash(userId, userCashHis);
        //开始分佣
        cashService.benefit(order.getUserId(), order.getOrderNo(), order.getAmount(), type, order.getChannelCode());

        this.notifyAgent(order);
        return true;
    }

    @Override
    public boolean finish(Long id) {
        return false;
    }

    @Override
    public void insertGoods() {
        List<Goods> goodsList = goodsService.list(new Goods());

        Order order = new Order();
        order.setGoodsStatus(0);
        PageDomain pageDomain = new PageDomain();
        pageDomain.setPageSize(200);

        while (true) {


            List<Order> list = orderService.findPage(order, pageDomain).getList();
            if (CollectionUtil.isEmpty(list)) {
                break;
            }
            pageDomain.setPageNo(pageDomain.getPageNo() + 1);
            pageDomain.setPageNum(pageDomain.getPageNum());
            List<Order> result = new ArrayList<>();
            for (int i = 0; i < list.size(); i++) {
                Order order1 = list.get(i);
                Goods goods = this.getGoods(goodsList, order1);
                Order domain = new Order();
                domain.setGoodsStatus(1);
                domain.setId(order1.getId());
                domain.setGoodsName(goods.getName());
                domain.setGoodsPic(goods.getPic());
                result.add(domain);
            }
            orderService.updateBatchById(result);
        }
    }

    private Goods getGoods(List<Goods> goodsList, Order order) {

        for (int i = 0; i < goodsList.size(); i++) {
            Goods goods = goodsList.get(i);

            if (order.getPayAmount().compareTo(goods.getMinPrice()) > 0 &&
                    order.getPayAmount().compareTo(goods.getMaxPrice()) <= 0) {

                return goods;
            }

        }
        return goodsList.get(0);
    }

    //回调下游
    @Transactional
    public void notifyAgent(Order orderReceive) {

        if (StrUtil.equals(OrderStatusEnum.success.getValue(), orderReceive.getOrderStatus())) {
            //已收款
            CashHistory userCashHis = new CashHistory(orderReceive.getMerchantId(), orderReceive.getActualAmount(), "add", "代收到账", "orderReceive");
            userCashHis.setOrderNo(orderReceive.getOrderNo());
            cashService.updateCash(orderReceive.getMerchantId(), userCashHis);
            orderReceive.setStatus("finish");
        } else {
            orderReceive.setStatus("timeout");
        }
        orderService.updateDomain(orderReceive);
        if (!StrUtil.equals(OrderStatusEnum.success.getValue(), orderReceive.getOrderStatus())) {

            return;
        }

        threadPoolTaskExecutor.execute(() -> {
            //回调下游
            SysUser sysUser = userService.check(orderReceive.getMerchantId());
            ApiNotifyDto apiNotifyDto = BeanUtil.copyProperties(orderReceive, ApiNotifyDto.class);
            apiNotifyDto.setMerchantId(orderReceive.getMerchantId());
            apiNotifyDto.setType(OrderTypeEnum.receive.getValue());
            apiNotifyDto.setStatus(orderReceive.getOrderStatus());
            apiNotifyDto.setPic(null);
            String serSign = SignMD5Util.getSerSign(apiNotifyDto, sysUser.getSecertKey());
            apiNotifyDto.setSign(serSign);

            int i = 0;
            while (i < 5) {
                String result = RequestUtil.request(orderReceive.getNotifyUrl(), apiNotifyDto, MediaType.APPLICATION_JSON, HttpMethod.POST, null);

                log.info("代收回调下游参数：{},结果:{}", JSONObject.toJSONString(apiNotifyDto), result);
                if (StrUtil.equals("SUCCESS", result) || StrUtil.equals("success", result)) {
                    orderReceive.setReturnStatus(1);
                    orderService.updateDomain(orderReceive);
                    break;
                }
                try {
                    Thread.sleep(30000L);
                    i++;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        });
    }

}